package com.aisile.admin.service.impl;

import com.aisile.admin.mapper.AdChannelMapper;
import com.aisile.admin.service.AdChannelService;
import com.aisile.common.exception.CustomException;
import com.aisile.common.exception.CustomExceptionThrows;
import com.aisile.model.admin.dtos.ChannelDto;
import com.aisile.model.admin.pojos.AdChannel;
import com.aisile.model.common.dtos.PageResponseResult;
import com.aisile.model.common.dtos.ResponseResult;
import com.aisile.model.common.enums.AdminHttpCodeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @Auther:yry
 * @Date:2024/4/22 0022
 * @VERSON:1.0
 */
@Service
public class AdChannelServiceImpl extends ServiceImpl<AdChannelMapper, AdChannel> implements AdChannelService {
    @Override
    public ResponseResult findListByPage(ChannelDto dto) {
        // 开发思路  1.先判断错  稍后根据自己的业务看是否需要判断对
        if (dto == null) {

            CustomExceptionThrows.catchAdmin(AdminHttpCodeEnum.PARAM_REQUIRE);
            //return ResponseResult.errorResult(AdminHttpCodeEnum.PARAM_REQUIRE);
        }
        int i = 9/0;
        // 初始化分页参数  dto 为什么不用new，因为在controller层 json转对象 已经帮着new
        dto.checkParam();
        // 开始拼接条件
        LambdaQueryWrapper<AdChannel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //StringUtils.isNotEmpty();  isNotEmpty()方法会将空字符进行判断，有空字符也会判断为不空-true；
        //StringUtils.isNotBlank();  而isNotBlank()方法只对非空字符进行判断。
        lambdaQueryWrapper.like(StringUtils.isNotBlank(dto.getName()), AdChannel::getName, dto.getName());
        // 分页
        Page page = new Page(dto.getPage(), dto.getSize());
        IPage<AdChannel> iPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
        //  ((Long)iPage.getTotal()).intValue()
        ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), Integer.valueOf(iPage.getTotal() + ""));
        responseResult.setData(iPage.getRecords());
        return responseResult;
    }

    @Override
    public ResponseResult saveAdChannel(AdChannel adChannel) {
        // 双重校验  前端校验一遍  后端校验一遍
        // 如果是|| 从左向右判断 依次判断  true之后继续判断
        // 如果是&& 要看所有条件执行情况
        if (adChannel == null || adChannel.getName() == null || StringUtils.isBlank(adChannel.getName())) {
            return ResponseResult.errorResult(AdminHttpCodeEnum.PARAM_REQUIRE);
        }
        // 接口幂等性 数据重复 重复请求，返回的值是一样的 就是幂等 返回的值不一样 就是不幂等
        // 当请求是否可以改变服务器端数据 能改变 就不安全  不能改变就是安全
        // get请求 天然幂等且安全  post请求 不幂等且不安全  put请求 幂等且不安全  delete请求 幂等且不安全
        // 所谓的线程安全是什么？ 当多线程访问同一数据源（除redis以外）就是线程不安全
        // 频道添加会不会添加重复的数据？ 如果不想让数据重复添加  有几种方式？
        // 1. 业务上 先查后插方式 配合 数据库锁或者分布式锁
        // 2. 数据库中 添加唯一约束（后端代码）
        int i = this.count(Wrappers.<AdChannel>lambdaQuery().eq(
                AdChannel::getName, adChannel.getName()
        ));
        if (i > 0) {
            return ResponseResult.errorResult(AdminHttpCodeEnum.PARAM_REQUIRE);
        }
        // 可以添加了
        // 需要自维护创建时间
        adChannel.setCreatedTime(new Date());
        this.save(adChannel);
        return ResponseResult.okResult(AdminHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult updateAdChannel(Integer id, AdChannel adChannel) {
        if (adChannel == null || adChannel.getName() == null || "".equals(adChannel.getName().trim()) || id == null) {
            return ResponseResult.errorResult(AdminHttpCodeEnum.PARAM_REQUIRE);
        }
        // 先根据id查询是否有修改的对象
        AdChannel adChannelOld = this.getById(id);
        if (adChannelOld == null) {
            return ResponseResult.errorResult(AdminHttpCodeEnum.PARAM_REQUIRE);
        }
        // 可以修改了
        adChannel.setId(id);
        this.updateById(adChannel);
        return ResponseResult.okResult(AdminHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult updateCahnnelStatusById(Integer id, Integer type) {
        if (id == null || type == null) {
            return ResponseResult.errorResult(AdminHttpCodeEnum.PARAM_REQUIRE);
        }
        if (type > 1 || type < 0) {
            return ResponseResult.errorResult(AdminHttpCodeEnum.PARAM_REQUIRE);
        }
        AdChannel adChannelOld = this.getById(id);
        if (adChannelOld == null) {
            return ResponseResult.errorResult(AdminHttpCodeEnum.PARAM_REQUIRE);
        }
        adChannelOld.setStatus(type == 0 ? false : true);
        this.updateById(adChannelOld);
        return ResponseResult.okResult(AdminHttpCodeEnum.SUCCESS);
    }
}
